#include "QString"
#include <QPainter>
#include <QPushButton>
#include <QTimer>
#include <QDialog>
#include <vector>
#include <QDebug>
#include <QLabel>
#include <QtGlobal>
#include <QTime>
#include <QMenuBar>
#include <qfont.h>
#include <dialog.h>
#include <grid.h>
#include "mylabel.h"
#include "helper.h"
#include "mainwindow.h"
#include "game.h"

game::game(QWidget *parent, int length, int width, int num) : QMainWindow(parent) {
    this->setFixedSize(length * 40 + 80, width * 40 + 80);
    this->num = num;
    now_time = new QLabel(this);
    start_timer = false;
    len = length;
    wid = width;
    now_num = num;
    QFont number_font("Microsoft YaHei", 12);
    QFont Menu_font("Microsoft YaHei", 12, 75);
    QFont mine_font("Gungsuh", 20);
    //-----时间、雷数的显示-----
    QLabel *text_1 = new QLabel(this);
    QLabel *text_2 = new QLabel(this);
    QLabel *now_number = new QLabel(this);
    text_1->move(length * 40 * 0.65, width * 40 + 40);
    text_1->setFont(number_font);
    text_1->setText("剩余雷数:");
    text_2->move(length * 40 * 0.15, width * 40 + 40);
    text_2->setFont(number_font);
    text_2->setText("花费时间:");
    now_number->move(length * 40 * 0.65 + 120, width * 40 + 40);
    now_number->setFont(number_font);
    now_number->setText(QString::number(now_num));
    now_time->move(length * 40 * 0.15 + 120, width * 40 + 40);
    now_time->setFont(number_font);
    now_time->setText(QString::number(this->time_spent));
    QMenuBar *bar = menuBar();
    setMenuBar(bar);
    bar->setFont(Menu_font);
    QMenu *startMenu = bar->addMenu("· · ·");
    QAction *help = startMenu->addAction("帮助");
    QAction *back = startMenu->addAction("返回");
    QAction *quit = startMenu->addAction("退出");
    //-----菜单各action功能实现-----
    connect(help, &QAction::triggered, [=]() {
        helper *helplist = new helper;
        helplist->show();
    });
    connect(back, &QAction::triggered, [=]() {
        this->close();
        MainWindow *window = new MainWindow();
        window->show();
    });
    connect(quit, &QAction::triggered, [=]() {
        this->close();
    });
    //-----生成随机地雷(排除重复)-----
    bool map[40][40];
    for (int i = 0; i < 40; i++) {
        for (int j = 0; j < 40; j++) {
            map[i][j] = false;
        }
    }
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
    for (int i = 0; i < num; i++) {
        int x = qrand() % length;
        int y = qrand() % width;
        if (!map[x][y]) {
            map[x][y] = true;
        } else {
            i--;
        }
    }
    //-----初始化地图-----
    for (int i = 0; i < length; i++) {
        for (int j = 0; j < width; j++) {
            if (map[i][j]) {
                grid *btn = new grid(i, j, 0);
                btn->setParent(this);
                btn->move(i * 40 + 40, j * 40 + 40);
                minemap[i][j] = btn;
            } else {
                grid *btn = new grid(i, j, 1);
                btn->setParent(this);
                btn->move(i * 40 + 40, j * 40 + 40);
                minemap[i][j] = btn;
            }
            //----已标记地雷的数目改变(标记/取消标记操作时调用)----
            connect(minemap[i][j], &grid::change_num, [=]() {
                now_num = num;
                for (int i = 0; i < length; i++) {
                    for (int j = 0; j < width; j++) {
                        if (minemap[i][j]->marked == true) now_num--;
                    }
                }
                now_number->setText(QString::number(now_num));
            });
            //----点击方块----
            connect(minemap[i][j], &QPushButton::clicked, [=]() {
                //---首次点击 开始计时---
                if (start_timer == false) {
                    startTimer(1000);
                    start_timer = true;
                }
                //---禁用按钮(游戏结束或者方块已被标记)---
                if (minemap[i][j]->finished || minemap[i][j]->marked) return;
                //---是否踩雷---
                if (!minemap[i][j]->type) {
                    //--显示所有地雷位置--
                    for (int i = 0; i < length; i++) {
                        for (int j = 0; j < width; j++) {
                            minemap[i][j]->finished = true;
                            if (minemap[i][j]->type == 0) {
                                minemap[i][j]->hide();
                                QLabel *mine_label = new QLabel("*", this);
                                mine_label->setFont(mine_font);
                                mine_label->setFixedSize(40, 40);
                                mine_label->move(i * 40 + 40, j * 40 + 40);
                                mine_label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                                mine_label->show();
                            }
                        }
                    }
                    //--游戏失败对话框--
                    QTimer::singleShot(200, this, [=]() {
                        start_timer = false;
                        dialog *failed = new dialog("游戏失败！！", len, wid, num, -1);
                        failed->show();
                        connect(failed, &dialog::newgame, this, [=]() {
                            failed->close();
                            this->close();
                        });
                        connect(failed, &dialog::Backtomenu, this, [=]() {
                            this->close();
                        });
                    });
                } else {
                    //--搜索--
                    dfs(minemap[i][j]->posx, minemap[i][j]->posy);
                }
                //---判断游戏胜利---
                if (isWin()) {
                    for (int i = 0; i < length; i++) {
                        for (int j = 0; j < width; j++) {
                            minemap[i][j]->finished = true;
                        }
                    }
                    //--游戏胜利对话框--
                    QTimer::singleShot(200, this, [=]() {
                        start_timer = false;
                        dialog *win = new dialog("游戏胜利！！", len, wid, num, time_spent);
                        connect(win, &dialog::newgame, this, [=]() {
                            win->close();
                            this->close();
                        });
                        win->show();
                        connect(win, &dialog::Backtomenu, this, [=]() {
                            this->close();
                        });
                    });
                };
            });
        }
    }
}

//-----判断胜利-----
bool game::isWin() {
    int ans = 0;
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < wid; j++) {
            ans += minemap[i][j]->nowtype;
        }
    }
    if (ans == 0) return true;
    else return false;
}

//-----判断界内-----
bool game::infield(int x, int y) {
    if (x < len && x >= 0 && y < wid && y >= 0) return true;
    else return false;
}

//-----搜索-----
void game::dfs(int x, int y) {
    int num = 0;
    minemap[x][y]->nowtype = 0;
    for (int k = 0; k < 8; k++) {
        if (infield(x + dx[k], y + dy[k]) &&
            minemap[x + dx[k]][y + dy[k]]->type == 0) {
            num++;
        }
    }
    minemap[x][y]->hide();
    if (num == 0) {
        //----白板 搜索周围的方块----
        MyLabel *blank_label = new MyLabel;
        blank_label->setParent(this);
        blank_label->setFrameShape(QFrame::Box);
        blank_label->setStyleSheet("border-width:1px;border-style:solid;border-color:rgb(222,222,222);");
        blank_label->setFixedSize(40, 40);
        blank_label->move(x * 40 + 40, y * 40 + 40);
        blank_label->num = num;
        blank_label->show();
        for (int k = 0; k < 8; k++) {
            if (infield(x + dx[k], y + dy[k]) &&
                minemap[x + dx[k]][y + dy[k]]->nowtype != 0) {
                dfs(x + dx[k], y + dy[k]);
            }
        }
        return;
    } else {
        //----标记数字 初始化数字MyLabel----
        MyLabel *label = new MyLabel();
        QFont label_font("Gungsuh", 20);
        label->setFrameShape(QFrame::Box);
        label->setStyleSheet("border-width:1px;border-style:solid;border-color:rgb(222,222,222);");
        label->setFont(label_font);
        label->setParent(this);
        label->setText(QString::number(num));
        label->setFixedSize(40, 40);
        label->move(x * 40 + 40, y * 40 + 40);
        label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
        label->posx = x;
        label->posy = y;
        label->num = num;
        connect(label, &MyLabel::clean, this, [=]() {
            clickall(label->posx, label->posy, label->num);
        });
        label->show();
        return;
    }
}

//-----双击MyLabel触发快速清理-----
void game::clickall(int x, int y, int num) {
    int temp = 0;
    for (int k = 0; k < 8; k++) {
        if (infield(x + dx[k], y + dy[k])) {
            if (minemap[x + dx[k]][y + dy[k]]->marked) temp++;
        }
    }
    //----防止误操作----
    if (temp == num) {
        for (int k = 0; k < 8; k++) {
            if (infield(x + dx[k], y + dy[k])) {
                emit minemap[x + dx[k]][y + dy[k]]->clicked();
            }
        }
    }
};

//-----计时器-----
void game::timerEvent(QTimerEvent *) {
    if(this->start_timer == true){
        time_spent++;
        now_time->setText(QString::number(this->time_spent));
    };
}
